﻿using System;
using AiFrame.InterfaceLib.Configuration;
using AiFrame.InterfaceLib.Plugins.Events;
using AiFrame.InterfaceLib.Policy.ProductLine;
using AiFrame.InterfaceLib.Windows.Themes;

namespace AiFrame.InterfaceLib.Plugins
{
    /// <summary>
    /// Represents a plugin manager which is able to load and unload
    /// plugins.
    /// </summary>
    public interface IPluginManager: IWindowRegisteredEvent, IConnectionReadyEvent
    {
        /// <summary>
        /// Loads all system libraries (product line, theme, etc.).
        /// </summary>
        void LoadSystemLibraries();

        /// <summary>
        /// Loads all plugins listed in the configuration file.
        /// <param name="applicationPath">The startup path of the application, without closing "\\"</param>
        /// </summary>
        void LoadPlugins(string applicationPath);

        /// <summary>
        /// Unloads all plugin and disposes its resources.
        /// </summary>
        void UnloadPlugins();

        /// <summary>
        /// Initializes the plugin manager with a factory for
        /// the coreInterface.
        /// </summary>
        void Init(ICoreInterfaceFactory coreInterfaceFactory);

        /// <summary>
        /// Returns the current product line.
        /// </summary>
        IProductLine GetProductLine();

        /// <summary>
        /// Returns the application theme.
        /// </summary>
        ITheme GetApplicationTheme();

        /// <summary>
        /// Loads a configuration module for the configuration mode.
        /// </summary>
        /// <param name="filename">The path to the configuration module.</param>
        /// <returns>The configuration class.</returns>
        IStartupConfiguration LoadConfigurationModule(string filename);

        /// <summary>
        /// This event gets fired when all Plugins are informed of
        /// the WindowRegisteredEvent so they have loaded successfully.
        /// </summary>
        event EventHandler<WindowChangedEventArgs> WindowsLoadedReady;

        /// <summary>
        /// This event gets fired when a window wants to inform other
        /// windows that the dataset 
        /// </summary>
        event EventHandler<WindowChangedEventArgs> NewDatasetAssigned;

        /// <summary>
        /// Invokes the event that a window has assigned a new
        /// dataset.
        /// </summary>
        /// <param name="wnd">The window that has changed.</param>
        void InvokeNewDatasetAssignedEvent<T>(object subWindowContainer);
    }

    /// <summary>
    /// Event arguments for the WindowChanged event.
    /// </summary>
    public class WindowChangedEventArgs: EventArgs
    {
        public object Window { get; set;}

        public WindowChangedEventArgs(object wnd)
        {
            this.Window = wnd;
        }
    }
}